#ifndef TOOLS_H
#define TOOLS_H

#include <iostream>
#include <string>
#include <sstream>
#include <cstring>

#include <openssl/md5.h>
#include <netinet/in.h>

#define AV_BASE64_SIZE(x)   (((x)+2) / 3 * 4 + 1)
#define UINT_MAX    0xffffffff
#define NEED_CONVERT true

#define REC_BUFFER_LENGTH_FLV 2000000

class Tools
{
public:
    //十六进制辅助输出函数
    static void PrintStringToHex(const char* input, int length);
    static void PrintStringToHex(const uint8_t* input, int length);
    static std::string PrintIntToHex(int input);

    //64位字节序转换
    static void htonll(double val, uint8_t* ret);
    static void htonll(long val, uint8_t* ret);

    //指数哥伦布熵编码 解码函数
    static int SPSDecodeU(char* SPS, int& startIndex);
    static int SPSDecode(char* SPS, int& startIndex);

    //加密函数，用于rtsp鉴权
    static std::string ComputeMD5(const std::string& input);
    static std::string EncodeBase64(const std::string &txt);

    //用于写入文件或套接字
    static bool WriteFile(FILE* flie, int socketFd, uint8_t* buffer, size_t length, std::string errorMsg);
    static bool WriteFile(FILE* flie, int socketFd, char* buffer, size_t length, std::string errorMsg);
    static bool WriteFile(FILE* flie, int socketFd, int* buffer, size_t length, std::string errorMsg);
    
private:
    static char *av_base64_encode_l(char *out, int *out_size, const uint8_t *in, int in_size);
};

class DataNode
{
public:
    DataNode(int preNodeIndex)
    {
        startIndex = 0;
        endIndex = 0;
        naluType = -1;
        timestamp = 0;
        next = NULL;
        packageType = -1;
        naluLength = 0;
        nodeIndex = preNodeIndex + 1;
    }
    ~DataNode(){}

    void SetStart(int _startIndex, int _naluType, int _timestamp)
    {
        startIndex = _startIndex;
        naluType = _naluType;
        timestamp = _timestamp;
    }

    //返回当前分片的长度
    int SetEnd(int _endIndex)
    {
        endIndex = _endIndex;
        next = new DataNode(nodeIndex);

        int seqLength = endIndex - startIndex;
        return (seqLength > 0 ? seqLength : seqLength + REC_BUFFER_LENGTH_FLV);
    }

    int startIndex;
    int endIndex;
    int naluType;
    int timestamp;
    int packageType;//0为单包，1为分片起点，2为分片终点
    int naluLength;//仅第一个分包的该变量有效
    DataNode* next;
    int nodeIndex;
};

#endif
